package com.xhwl.centiotdata.controller;


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xhwl.centiotdata.integration.parkingguidance.ParkingGuidanceFactory;
import com.xhwl.centiotdata.integration.parkingguidance.ParkingGuidanceIntegrationConfig;
import com.xhwl.centiotdata.service.cent.ICentAlarmService;
import com.xhwl.centiotdata.service.cent.IDeviceCentService;
import com.xhwl.centiotdata.service.cent.ISpaceCentService;
import com.xhwl.centiotdata.service.vehicleschedule.VehicleScheduleServiceImpl;
import com.xhwl.centiotdata.utils.ServletUtils;
import com.xhwl.common.dto.cent.device.DeviceDTO;
import com.xhwl.common.dto.cent.iotdata.vehicleschedule.VehicleScheduleRequestsDTO;
import com.xhwl.common.dto.cent.iotdata.vehicleschedule.VehicleScheduleResponseDTO;
import com.xhwl.common.enums.CategoryEnum;
import com.xhwl.common.pojo.ResultJson;
import com.xhwl.common.pojo.cent.sdata.Organization;
import com.xhwl.common.pojo.cent.sdata.OrganizationType;
import com.xhwl.common.query.cent.device.DevicePageQuery;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 地磁推送数据的类
 */
@Slf4j
@RestController
public class geoDataPushController {

    @Autowired
    private IDeviceCentService deviceCentService;

    @Autowired
    private ParkingGuidanceFactory parkingGuidanceFactory;

    @Autowired
    private ISpaceCentService spaceCentService;

    @Autowired
    private ICentAlarmService centAlarmService;

    @Autowired
    private VehicleScheduleServiceImpl vehicleScheduleService;

    private static final String cmd = "spaceStatus";
    private static final String secret = "785aec484164d44e191da7fd852bd1";
    private static final String code = "951002628";
    private static final Integer spaceFree = 1;
    private static final Integer spaceUse = 0;
    private static final String event_type_in = "IN";
    private static final String event_type_out = "OUT";

    /**
     * 科拓地磁推送地磁状态的接口
     */
    @PostMapping("/ke-top-mn/space-status")
    public void spaceStatus(HttpServletRequest request, HttpServletResponse response){
        String spaceStatusStr = this.onGettingBody(request);
        JSONObject spaceStatusObj = JSONObject.parseObject(spaceStatusStr);
        log.info("科拓地磁变更状态推送：{}", JSONObject.toJSONString(spaceStatusObj));
        HashMap<String, Object> respData = new HashMap<>();

        //鉴权，暂时只查验是否有cmd字段的值
        if(spaceStatusObj.getString("cmd")!=null){
            JSONObject spaceStatusData = JSONObject.parseObject(spaceStatusObj.getString("data"));
            JSONArray spaceStatusDataArr = JSONObject.parseArray(spaceStatusData.getString("carList"));
            log.info("科拓地磁的数据部分为：{}", spaceStatusDataArr.toString());
            //根据科拓地磁发送的信息，来做业务代码
            for (Object object : spaceStatusDataArr) {
                JSONObject spaceStatusDataObj = JSONObject.parseObject(object.toString());
                if(spaceStatusDataObj.getString("busNumber") != null){
                    Map<Integer, List<ParkingGuidanceIntegrationConfig>> integerListMap = parkingGuidanceFactory.onFindingIntegrationConfigs();
                    integerListMap.forEach(
                            (key, value)->{
                                if(!value.isEmpty()){
                                    value.forEach(integrationConfig->{
                                        String[] cmdList = integrationConfig.getCmd().split(",");
                                        String cmdThird = Arrays.stream(cmdList).filter(c -> StringUtils.equals(c, cmd)).findAny().orElse(null);
                                        if(cmdThird == null){
                                            return;
                                        }
                                        DevicePageQuery deviceQuery = new DevicePageQuery();
                                        deviceQuery.setProjectId(integrationConfig.getProjectId());
                                        deviceQuery.setThirdDeviceId(spaceStatusDataObj.getString("busNumber"));
                                        List<DeviceDTO> deviceDTOS = deviceCentService.listDevice(null, deviceQuery);
                                        if(!deviceDTOS.isEmpty()){
                                            DeviceDTO deviceDTO = deviceDTOS.get(0);
                                            VehicleScheduleRequestsDTO vehicleScheduleRequestsDTO = this.deviceInfoToPosition(deviceDTO);
                                            if(vehicleScheduleRequestsDTO == null){
                                                return;
                                            }
                                            vehicleScheduleRequestsDTO.setProjectId(integrationConfig.getProjectId());
                                            //如果地磁状态为0，代表是车辆进入到地磁上，即地磁被占用
                                            if(spaceStatusDataObj.getInteger("stopFlag").equals(spaceUse)){
                                                if(integrationConfig.getSyncSpaceStatus() == null || !integrationConfig.getSyncSpaceStatus()){
                                                    log.info("项目id为{}，未开启同步地磁变更状态的功能", integrationConfig.getProjectId());
                                                }else if(integrationConfig.getSyncSpaceStatus()){
                                                    log.info("项目id为{}，开启了同步地磁变更状态的功能，开始通知车辆调度", integrationConfig.getProjectId());
                                                    vehicleScheduleRequestsDTO.setEventType(event_type_in);
                                                    log.info("项目id为{}，同步地磁变更状态的请求参数为：{}", integrationConfig.getProjectId(),JSONObject.toJSONString(vehicleScheduleRequestsDTO));
                                                    ResultJson<VehicleScheduleResponseDTO> resultJson = vehicleScheduleService.onSyncingSpaceStatus(vehicleScheduleRequestsDTO);
                                                    log.info("项目id为{}，同步地磁变更状态的响应参数为：{}", integrationConfig.getProjectId(),JSONObject.toJSONString(resultJson));
                                                }
                                            }
                                            //如果地磁状态为1，代表是车辆离开地磁上，即地磁处于非占用
                                            else if(spaceStatusDataObj.getInteger("stopFlag").equals(spaceFree)){
                                                //判断这个组织id中是否存在摄像头设备，如果存在，就做地磁与摄像头的联动功能
                                                DevicePageQuery devicePageQuery = new DevicePageQuery();
                                                devicePageQuery.setProjectId(integrationConfig.getProjectId());
                                                devicePageQuery.setOrganizationId(deviceDTO.getOrganizationId());
                                                devicePageQuery.setCategoryId(CategoryEnum.MONITOR.getId());
                                                List<DeviceDTO> deviceDTOList = deviceCentService.listDevice(null, devicePageQuery);
                                                if(!deviceDTOList.isEmpty()){
                                                    log.info("项目id为{}，该地磁绑定的路址上存在摄像头，故开始联动功能", integrationConfig.getProjectId());
                                                    vehicleScheduleRequestsDTO.setEventType(event_type_out);
                                                    log.info("项目id为{}，地磁请求摄像头的参数为：{}", integrationConfig.getProjectId(),JSONObject.toJSONString(vehicleScheduleRequestsDTO));
                                                    ResultJson resultJson = centAlarmService.vehicleWagonBalanceEvent(vehicleScheduleRequestsDTO);
                                                    log.info("项目id为{}，地磁请求摄像头的响应参数为：{}", integrationConfig.getProjectId(), JSONObject.toJSONString(resultJson));
                                                }else{
                                                    log.info("项目id为{}，该地磁绑定的路址上不存在摄像头", integrationConfig.getProjectId());
                                                    if(integrationConfig.getSyncSpaceStatus() == null || !integrationConfig.getSyncSpaceStatus()){
                                                        log.info("项目id为{}，未开启同步地磁变更状态的功能", integrationConfig.getProjectId());
                                                    }else if(integrationConfig.getSyncSpaceStatus()){
                                                        //不做联动功能的地磁，需要通知车辆调度那边地磁实时变更状态
                                                        log.info("项目id为{}，开启了同步地磁变更状态的功能，开始通知车辆调度", integrationConfig.getProjectId());
                                                        vehicleScheduleRequestsDTO.setEventType(event_type_out);
                                                        log.info("项目id为{}，同步地磁变更状态的请求参数为：{}", integrationConfig.getProjectId(),JSONObject.toJSONString(vehicleScheduleRequestsDTO));
                                                        ResultJson<VehicleScheduleResponseDTO> resultJson = vehicleScheduleService.onSyncingSpaceStatus(vehicleScheduleRequestsDTO);
                                                        log.info("项目id为{}，同步地磁变更状态的响应参数为：{}", integrationConfig.getProjectId(),JSONObject.toJSONString(resultJson));
                                                    }
                                                }
                                            }
                                            else{
                                                log.error("项目id为{}，科拓地磁发送的车位状态不存在于文档中", integrationConfig.getProjectId());
                                            }
                                        }else{
                                            log.info("项目id为{}，通过车位编码{}，未找到相应的地磁设备", integrationConfig.getProjectId(), spaceStatusDataObj.getString("busNumber"));
                                        }
                                    });
                                }
                            }
                    );
                }else{
                    log.error("科拓地磁厂商未发送车位编号信息");
                }
            }
            respData.put("success", true);
            respData.put("code", code);
            ServletUtils.RespToWrite(response,respData);
        }else{
            log.error("此推送接口很可能不是科拓地磁厂商发送的");
            respData.put("success", false);
            respData.put("code", code);
            ServletUtils.RespToWrite(response,respData);
        }
    }

    /**
     * 根据设备信息，获取设备的点位信息
     */
    private VehicleScheduleRequestsDTO deviceInfoToPosition(DeviceDTO deviceDTO){
        VehicleScheduleRequestsDTO vehicleScheduleRequestsDTO = new VehicleScheduleRequestsDTO();
        Organization organization = spaceCentService.getById(deviceDTO.getOrganizationId());
        //由于space类型的组织的编码不是存储在组织表中，而是存储在space表中
        if(!StringUtils.isEmpty(organization.getCode())){
            vehicleScheduleRequestsDTO.setPositionId(organization.getCode());
        }else{
            ResultJson spaceResult = spaceCentService.detail(null, organization.getId());
            log.info("组织表里面没有code信息，请求space结果为：{}，", JSONObject.toJSONString(spaceResult));
            if (spaceResult == null || !spaceResult.getState()){
                log.info("获取space信息失败");
                return null;
            }
            JSONObject spaceObject = JSONObject.parseObject(
                    JSONObject.parseObject(JSONObject.toJSONString(spaceResult.getResult())).getString("data"));
            if(StringUtils.isEmpty(spaceObject.getString("code"))){
                log.info("space中没有code信息");
                return null;
            }
            vehicleScheduleRequestsDTO.setPositionId(spaceObject.getString("code"));
        }
        vehicleScheduleRequestsDTO.setPositionName(organization.getName());
//        organizationService.list(null);
        List<OrganizationType> organizationTypeList = spaceCentService.getOrgTypeList(null);
        organizationTypeList.stream().filter(organizationType1 -> organizationType1.getId().equals(organization.getType()))
                .findAny().ifPresent(organizationType -> vehicleScheduleRequestsDTO.setPositionType(organizationType.getCode()));

        return vehicleScheduleRequestsDTO;
    }

    private String onGettingBody(HttpServletRequest request) {
        try {
            BufferedReader reader = request.getReader();
            char[] buf = new char[512];
            int len = 0;
            StringBuffer contentBuffer = new StringBuffer();
            while ((len = reader.read(buf)) != -1) {
                contentBuffer.append(buf, 0, len);
            }
            return contentBuffer.toString();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}
